package cn.tj.wenda.cloud.mapper;

import org.apache.ibatis.annotations.DeleteProvider;
import org.apache.ibatis.mapping.MappedStatement;
import tk.mybatis.mapper.MapperException;
import tk.mybatis.mapper.annotation.RegisterMapper;
import tk.mybatis.mapper.entity.EntityColumn;
import tk.mybatis.mapper.mapperhelper.EntityHelper;
import tk.mybatis.mapper.mapperhelper.MapperHelper;
import tk.mybatis.mapper.mapperhelper.MapperTemplate;
import tk.mybatis.mapper.mapperhelper.SqlHelper;

import java.util.List;
import java.util.Set;

@RegisterMapper
public interface CloudDeleteMapper<T> {

    /**
     * 根据主键字段进行删除，方法参数必须包含完整的主键属性，
     * 此方法会自动启用乐观锁校验
     * @param key 关键字
     * @return
     */
    @DeleteProvider(type = SQLProvider.class, method = "dynamicSQL")
    int deleteByPrimaryKey(Object key);

    /**
     * 根据Example条件删除数据
     *
     * @param example
     * @return
     */
    @DeleteProvider(type = SQLProvider.class, method = "dynamicSQL")
    int deleteByExample(Object example);

    /**
     * 根据关键字List删除 根据主键字符串进行删除，类中只有存在一个带有@Id注解的字段
     *
     * @param ids
     * @return
     */
    @DeleteProvider(type = SQLProvider.class, method = "dynamicSQL")
    int deleteByIds(List<String> ids);

    class SQLProvider extends MapperTemplate {

        public SQLProvider(Class<?> mapperClass, MapperHelper mapperHelper) {
            super(mapperClass, mapperHelper);
        }

        /**
         * 通过主键删除
         *
         * @param ms
         */
        public String deleteByPrimaryKey(MappedStatement ms) {
            final Class<?> entityClass = getEntityClass(ms);
            StringBuilder sql = new StringBuilder();
            sql.append(SqlHelper.deleteFromTable(entityClass, tableName(entityClass)));
            sql.append(CloudSqlHelper.wherePKColumns(entityClass));
            return sql.toString();
        }

        /**
         * 根据Example删除
         *
         * @param ms
         * @return
         */
        public String deleteByExample(MappedStatement ms) {
            Class<?> entityClass = getEntityClass(ms);
            StringBuilder sql = new StringBuilder();
            if (isCheckExampleEntityClass()) {
                sql.append(SqlHelper.exampleCheck(entityClass));
            }
            //如果设置了安全删除，就不允许执行不带查询条件的 delete 方法
            if (getConfig().isSafeDelete()) {
                sql.append(SqlHelper.exampleHasAtLeastOneCriteriaCheck("_parameter"));
            }
            sql.append(SqlHelper.deleteFromTable(entityClass, tableName(entityClass)));
            sql.append(CloudSqlHelper.exampleWhereClause());
            return sql.toString();
        }

        /**
         * 根据关键字List删除，只能在单一主键情况下使用
         *
         * @param ms
         * @return
         */
        public String deleteByIds(MappedStatement ms) {
            final Class<?> entityClass = getEntityClass(ms);
            StringBuilder sql = new StringBuilder();
            sql.append(SqlHelper.deleteFromTable(entityClass, tableName(entityClass)));
            Set<EntityColumn> columnList = EntityHelper.getPKColumns(entityClass);
            if (columnList.size() == 1) {
                EntityColumn column = columnList.iterator().next();
                sql.append(" WHERE ${@cn.tj.wenda.cloud.util.LoginUser@getAuthorityWhere()} AND ");
                sql.append(column.getColumn());
                sql.append("<foreach collection='list' item='id' open='(' close=')' separator=','>");
                sql.append("#{id}");
                sql.append("</foreach>");
                //sql.append(" IN (${_parameter})");
            } else {
                throw new MapperException("继承 deleteByIds 方法的实体类[" + entityClass.getCanonicalName() + "]中必须只有一个带有 @Id 注解的字段");
            }
            return sql.toString();
        }

    }
}
